package com.shsh.safemanage.action;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.shsh.safemanage.dao.DaoCreator;
import com.shsh.safemanage.dao.DepartmentDao;
import com.shsh.safemanage.dao.EquipmentDao;
import com.shsh.safemanage.dao.HSEProblemDao;
import com.shsh.safemanage.model.Department1;
import com.shsh.safemanage.model.Equipment;
import com.shsh.safemanage.model.HSECategoryCause;
import com.shsh.safemanage.model.HSEMonthCompareReport;
import com.shsh.safemanage.model.HSEMonthDetailReport;
import com.shsh.safemanage.model.HSEReport;
import com.shsh.safemanage.model.HSEReportUnit;
import com.shsh.safemanage.model.HSEReportUnitImpl;
import com.shsh.safemanage.model.ProblemBrowseCondition;
import com.shsh.safemanage.util.Constants;
import com.shsh.safemanage.util.MessageUtil;
import com.shsh.safemanage.util.Util;

public class BrowseHSEAction {
	public HSEReport<HSEReportUnit> browseHSEMonthReport(HttpServletRequest request) {
		HttpSession session = request.getSession();

		String depart1IDStr = null, equipIDStr = null, dateStart = null, dateEnd = null, writerDepartment1IDStr = null;

		ProblemBrowseCondition condition = (ProblemBrowseCondition) session.getAttribute(Constants.SESSION_PROBLEM_CONDITION);
		if (condition != null) {
			depart1IDStr = condition.getDepart1IDStr();
			equipIDStr = condition.getEquipIDStr();
			dateStart = condition.getDateStart();
			dateEnd = condition.getDateEnd();
			writerDepartment1IDStr = condition.getWriterDepartment1ID();
		} else {
			depart1IDStr = request.getParameter(Constants.REQUEST_PARAMETER_DEPARTMENT_ID);
			equipIDStr = request.getParameter(Constants.REQUEST_PARAMETER_EQUIP_ID);
			dateStart = request.getParameter(Constants.REQUEST_PARAMETER_DATE_START);
			dateEnd = request.getParameter(Constants.REQUEST_PARAMETER_DATE_END);
			writerDepartment1IDStr = request.getParameter(Constants.REQUEST_PARAMETER_DEPARTMENT1ID_1);

			condition = new ProblemBrowseCondition();
			condition.setDepart1IDStr(depart1IDStr);
			condition.setEquipIDStr(equipIDStr);
			condition.setDateStart(dateStart);
			condition.setDateEnd(dateEnd);
			condition.setWriterDepartment1ID(writerDepartment1IDStr);

			session.setAttribute(Constants.SESSION_PROBLEM_CONDITION, condition);
		}

		Long depart1ID = null;
		try {
			depart1ID = new Long(depart1IDStr);
		} catch (Exception e) {
		}

		Long equipID = null;
		try {
			equipID = new Long(equipIDStr);
		} catch (Exception e) {
		}
		Long writerDepartment1ID = null;
		try {
			writerDepartment1ID = new Long(writerDepartment1IDStr);
		} catch (Exception e) {
		}

		if (Util.isNullOrEmpty(dateStart) || Util.isNullOrEmpty(dateEnd)) {
			request.setAttribute(Constants.REQUEST_ATTRIBUTE_ERROR, Constants.ERROR_KEY_DATE_SCOPE_NEEDED);
			return null;
		}

		Calendar calStart = Util.convertStrToDate(dateStart);
		Calendar calEnd = Util.convertStrToDate(dateEnd);
		if (calStart.get(Calendar.YEAR) != calEnd.get(Calendar.YEAR) || calStart.get(Calendar.MONTH) != calEnd.get(Calendar.MONTH)
				|| calStart.after(calEnd)) {
			request.setAttribute(Constants.REQUEST_ATTRIBUTE_ERROR, Constants.ERROR_KEY_DATE_SCOPE_SAMEMONTH);
			return null;
		}

		HSEReport<HSEReportUnit> report = null;
		if (writerDepartment1ID != null && writerDepartment1ID == Constants.DEPARTMENT1_ID_HSEGUANLICHU) {
			// generate corporation month report
			report = this.generateCorpHSEReport(dateStart, dateEnd);
		} else {
			if (depart1ID == null) {
				request.setAttribute(Constants.REQUEST_ATTRIBUTE_ERROR, Constants.ERROR_KEY_INVALID_DEPARTMENT);
				return null;
			}
			// generate department month report
			report = this.generateDepartHSEReport(depart1ID, equipID, dateStart, dateEnd);
		}

		return report;
	}

	private void setHSEDepartMonthDetailReport(HSEReport<HSEReportUnit> report, Long depart1ID, Long equipID, String dateStart,
			String dateEnd) {
		List<Long> unitIDArray = null, actionCauseIDArray = null, statusCauseIDArray = null;
		HSEProblemDao hseDao = DaoCreator.createHSEProblemDao();
		DepartmentDao departDao = DaoCreator.createDepartmentDao();

		Department1 depart1 = departDao.getDepartment1ByID(depart1ID);
		HSEMonthDetailReport<HSEReportUnit> monthDetailReport = new HSEMonthDetailReport<HSEReportUnit>();
		report.setMonthDetailReport(monthDetailReport);

		monthDetailReport.setDepartment1ID(depart1ID);
		monthDetailReport.setDepartment1Name(depart1.getDepartmentName());
		monthDetailReport.setEquipID(equipID);
		monthDetailReport.setDayStart(Util.convertStrToDate(dateStart));
		monthDetailReport.setDayEnd(Util.convertStrToDate(dateEnd));

		monthDetailReport.setUnitList(getUnitList(depart1, equipID));
		unitIDArray = new ArrayList<Long>();
		for (HSEReportUnit unit : monthDetailReport.getUnitList()) {
			unitIDArray.add(unit.getId());
		}

		monthDetailReport.setDangerActionCauseList(getCauseList(Constants.HSE_CATEGORY_CAUSE_TYPE_DIRECT,
				Constants.HSE_CATEGORY_DANGER_ACTION));
		actionCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : monthDetailReport.getDangerActionCauseList()) {
			actionCauseIDArray.add(cause.getId());
		}

		monthDetailReport.setDangerStatusCauseList(getCauseList(Constants.HSE_CATEGORY_CAUSE_TYPE_DIRECT,
				Constants.HSE_CATEGORY_DANGER_STATUS));
		statusCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : monthDetailReport.getDangerStatusCauseList()) {
			statusCauseIDArray.add(cause.getId());
		}

		monthDetailReport.setDangerActionTable(new int[monthDetailReport.getUnitList().size()][monthDetailReport.getDangerActionCauseList()
				.size()]);
		monthDetailReport.setDangerStatusTable(new int[monthDetailReport.getUnitList().size()][monthDetailReport.getDangerStatusCauseList()
				.size()]);

		hseDao.fullfillHSEDepartMonthDetailReportTable(monthDetailReport, dateStart, dateEnd, Constants.HSE_CATEGORY_DANGER_ACTION,
				unitIDArray, actionCauseIDArray);
		monthDetailReport.setDangerActionCount(monthDetailReport.getDangerActionTable()[unitIDArray.indexOf(0l)][actionCauseIDArray
				.indexOf(0l)]);

		hseDao.fullfillHSEDepartMonthDetailReportTable(monthDetailReport, dateStart, dateEnd, Constants.HSE_CATEGORY_DANGER_STATUS,
				unitIDArray, statusCauseIDArray);
		monthDetailReport.setDangerStatusCount(monthDetailReport.getDangerStatusTable()[unitIDArray.indexOf(0l)][statusCauseIDArray
				.indexOf(0l)]);

		hseDao.fullfillHSEDepartMonthDetailReportProblemCount(monthDetailReport, dateStart, dateEnd);

		report.setMonthDetailReport(monthDetailReport);

	}

	private void setHSECorpMonthDetailReport(HSEReport<HSEReportUnit> report, String dateStart, String dateEnd) {
		List<Long> unitIDArray = null, actionCauseIDArray = null, statusCauseIDArray = null;
		HSEProblemDao hseDao = DaoCreator.createHSEProblemDao();

		HSEMonthDetailReport<HSEReportUnit> monthDetailReport = new HSEMonthDetailReport<HSEReportUnit>();
		report.setMonthDetailReport(monthDetailReport);

		monthDetailReport.setDayStart(Util.convertStrToDate(dateStart));
		monthDetailReport.setDayEnd(Util.convertStrToDate(dateEnd));

		monthDetailReport.setUnitList(getUnitList());
		unitIDArray = new ArrayList<Long>();
		for (HSEReportUnit unit : monthDetailReport.getUnitList()) {
			unitIDArray.add(unit.getId());
		}

		monthDetailReport.setDangerActionCauseList(getCauseList(Constants.HSE_CATEGORY_CAUSE_TYPE_DIRECT,
				Constants.HSE_CATEGORY_DANGER_ACTION));
		actionCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : monthDetailReport.getDangerActionCauseList()) {
			actionCauseIDArray.add(cause.getId());
		}

		monthDetailReport.setDangerStatusCauseList(getCauseList(Constants.HSE_CATEGORY_CAUSE_TYPE_DIRECT,
				Constants.HSE_CATEGORY_DANGER_STATUS));
		statusCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : monthDetailReport.getDangerStatusCauseList()) {
			statusCauseIDArray.add(cause.getId());
		}

		monthDetailReport.setDangerActionTable(new int[monthDetailReport.getUnitList().size()][monthDetailReport.getDangerActionCauseList()
				.size()]);
		monthDetailReport.setDangerStatusTable(new int[monthDetailReport.getUnitList().size()][monthDetailReport.getDangerStatusCauseList()
				.size()]);

		hseDao.fullfillHSECorpMonthDetailReportTable(monthDetailReport, dateStart, dateEnd, Constants.HSE_CATEGORY_DANGER_ACTION,
				unitIDArray, actionCauseIDArray);
		monthDetailReport.setDangerActionCount(monthDetailReport.getDangerActionTable()[unitIDArray.indexOf(0l)][actionCauseIDArray
				.indexOf(0l)]);

		hseDao.fullfillHSECorpMonthDetailReportTable(monthDetailReport, dateStart, dateEnd, Constants.HSE_CATEGORY_DANGER_STATUS,
				unitIDArray, statusCauseIDArray);
		monthDetailReport.setDangerStatusCount(monthDetailReport.getDangerStatusTable()[unitIDArray.indexOf(0l)][statusCauseIDArray
				.indexOf(0l)]);

		hseDao.fullfillHSECorpMonthDetailReportProblemCount(monthDetailReport, dateStart, dateEnd);

		report.setMonthDetailReport(monthDetailReport);

	}

	private HSEReport<HSEReportUnit> generateDepartHSEReport(Long depart1ID, Long equipID, String dateStart, String dateEnd) {
		HSEReport<HSEReportUnit> report = new HSEReport<HSEReportUnit>();

		setHSEDepartMonthDetailReport(report, depart1ID, equipID, dateStart, dateEnd);
		setHSECurrentMonthCompareReport(report, depart1ID, equipID, dateStart, dateEnd);
		setHSEPreviousMonthCompareReport(report, depart1ID, equipID, dateStart);

		return report;
	}

	private HSEReport<HSEReportUnit> generateCorpHSEReport(String dateStart, String dateEnd) {
		HSEReport<HSEReportUnit> report = new HSEReport<HSEReportUnit>();
		setHSECorpMonthDetailReport(report, dateStart, dateEnd);
		setHSECurrentMonthCompareReport(report, dateStart, dateEnd);
		setHSEPreviousMonthCompareReport(report, dateStart);

		return report;
	}

	private List<HSEReportUnit> getUnitList() {
		// Corp unit list
		DepartmentDao departDao = DaoCreator.createDepartmentDao();

		List<HSEReportUnit> unitList = new ArrayList<HSEReportUnit>();
		//unitList.addAll(departDao.getDepartment1List(Constants.DEPARTMENT_TYPE_JIGUAN));
		unitList.addAll(departDao.getDepartment1List(Constants.DEPARTMENT_TYPE_SHIYEBU));

		// Add xiaoji to the last position of unit list.
		unitList.add(new HSEReportUnitImpl(0l, MessageUtil.getMessage(Constants.LABEL_KEY_XIAOJI)));

		return unitList;
	}

	private List<HSEReportUnit> getUnitList(Department1 depart1, Long equipID) {
		EquipmentDao equipDao = DaoCreator.createEquipmentDao();

		List<HSEReportUnit> unitList = new ArrayList<HSEReportUnit>();
		if (equipID != null) {
			Equipment equip = equipDao.getEquipment(equipID);
			unitList.add(equip);
		} else {
			List<Equipment> equipList = equipDao.getEquipmentListFromDepart2();

			for (Equipment equip : equipList) {
				if (equip.getDepartmentID().equals(depart1.getId())) {
					unitList.add(equip);
				}
			}
		}
		// Add xiaoji to the last position of unit list.
		unitList.add(new HSEReportUnitImpl(0l, MessageUtil.getMessage(Constants.LABEL_KEY_XIAOJI)));

		return unitList;
	}

	private List<HSECategoryCause> getCauseList(Integer causeType, Integer directCauseType) {
		HSEProblemDao problemDao = DaoCreator.createHSEProblemDao();
		// add heji to the last position of cause list.
		List<HSECategoryCause> causeList = problemDao.getHSECategoryCause(causeType, directCauseType);
		HSECategoryCause actionHeji = new HSECategoryCause();
		actionHeji.setId(0l);
		actionHeji.setCauseName(MessageUtil.getMessage(Constants.LABEL_KEY_HEJI));
		causeList.add(actionHeji);

		return causeList;
	}

	private int[][] convertTable(int[][] detailTable) {
		int[][] compareTable = new int[detailTable[0].length][detailTable.length];
		for (int i = 0; i < detailTable.length; i++) {
			for (int j = 0; j < detailTable[i].length; j++) {
				compareTable[j][i] = detailTable[i][j];
			}
		}

		return compareTable;
	}

	private void setCompareTotalTable(HSEMonthCompareReport<HSEReportUnit> compareReport) {
		int[][] dangerActionTable = compareReport.getDangerActionTable();
		int[][] dangerStatusTable = compareReport.getDangerStatusTable();

		int[][] totalTable = new int[compareReport.getUnitList().size()][3];
		for (int unitIndex = 0; unitIndex < totalTable.length; unitIndex++) {
			totalTable[unitIndex][0] = dangerActionTable[dangerActionTable.length - 1][unitIndex];
			totalTable[unitIndex][1] = dangerStatusTable[dangerStatusTable.length - 1][unitIndex];
			totalTable[unitIndex][2] = totalTable[unitIndex][0] + totalTable[unitIndex][1];
		}

		compareReport.setTotalTable(totalTable);

		compareReport.setTotalCauseCount(totalTable[totalTable.length - 1][totalTable[0].length - 1]);
	}

	private void changeXiaojiHeji(HSEMonthCompareReport<HSEReportUnit> compareReport) {
		// change name to xiaoji
		List<HSECategoryCause> causeList = compareReport.getDangerActionCauseList();
		causeList.get(causeList.size() - 1).setCauseName(MessageUtil.getMessage(Constants.LABEL_KEY_XIAOJI));
		causeList = compareReport.getDangerStatusCauseList();
		causeList.get(causeList.size() - 1).setCauseName(MessageUtil.getMessage(Constants.LABEL_KEY_XIAOJI));

		// change name to heji
		List<HSEReportUnit> unitList = compareReport.getUnitList();
		unitList.set(unitList.size() - 1, new HSEReportUnitImpl(0l, MessageUtil.getMessage(Constants.LABEL_KEY_HEJI)));
	}

	private void setHSECurrentMonthCompareReport(HSEReport<HSEReportUnit> report, Long depart1ID, Long equipID, String dateStart,
			String dateEnd) {
		List<Long> remoteCauseIDArray;
		HSEProblemDao problemDao = DaoCreator.createHSEProblemDao();
		// prepare month compare report.
		HSEMonthDetailReport<HSEReportUnit> detailReport = report.getMonthDetailReport();
		HSEMonthCompareReport<HSEReportUnit> currentCompareReport = new HSEMonthCompareReport<HSEReportUnit>();
		currentCompareReport.setDepartment1ID(depart1ID);
		currentCompareReport.setDepartment1Name(detailReport.getDepartment1Name());
		currentCompareReport.setEquipID(detailReport.getEquipID());

		Calendar calStart = Util.convertStrToDate(dateStart);
		currentCompareReport.setYear(calStart.get(Calendar.YEAR));
		currentCompareReport.setMonth(calStart.get(Calendar.MONTH) + 1);
		currentCompareReport.setRemoteCauseList(problemDao.getHSECategoryCause(Constants.HSE_CATEGORY_CAUSE_TYPE_REMOTE, null));
		remoteCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : currentCompareReport.getRemoteCauseList()) {
			remoteCauseIDArray.add(cause.getId());
		}

		currentCompareReport.setUnitList(detailReport.getUnitList());
		currentCompareReport.setDangerActionCauseList(detailReport.getDangerActionCauseList());
		currentCompareReport.setDangerStatusCauseList(detailReport.getDangerStatusCauseList());
		changeXiaojiHeji(currentCompareReport);

		currentCompareReport.setDangerActionTable(convertTable(detailReport.getDangerActionTable()));
		currentCompareReport.setDangerStatusTable(convertTable(detailReport.getDangerStatusTable()));
		setCompareTotalTable(currentCompareReport);

		problemDao.fullfillHSEMonthCompareReportRemoteCauseTable(currentCompareReport, dateStart, dateEnd, remoteCauseIDArray);

		report.setCurrentCompareReport(currentCompareReport);
	}

	private void setHSECurrentMonthCompareReport(HSEReport<HSEReportUnit> report, String dateStart, String dateEnd) {
		List<Long> remoteCauseIDArray;
		HSEProblemDao problemDao = DaoCreator.createHSEProblemDao();
		// prepare month compare report.
		HSEMonthDetailReport<HSEReportUnit> detailReport = report.getMonthDetailReport();
		HSEMonthCompareReport<HSEReportUnit> currentCompareReport = new HSEMonthCompareReport<HSEReportUnit>();

		Calendar calStart = Util.convertStrToDate(dateStart);
		currentCompareReport.setYear(calStart.get(Calendar.YEAR));
		currentCompareReport.setMonth(calStart.get(Calendar.MONTH) + 1);
		currentCompareReport.setRemoteCauseList(problemDao.getHSECategoryCause(Constants.HSE_CATEGORY_CAUSE_TYPE_REMOTE, null));
		remoteCauseIDArray = new ArrayList<Long>();
		for (HSECategoryCause cause : currentCompareReport.getRemoteCauseList()) {
			remoteCauseIDArray.add(cause.getId());
		}

		currentCompareReport.setUnitList(detailReport.getUnitList());
		currentCompareReport.setDangerActionCauseList(detailReport.getDangerActionCauseList());
		currentCompareReport.setDangerStatusCauseList(detailReport.getDangerStatusCauseList());
		changeXiaojiHeji(currentCompareReport);

		currentCompareReport.setDangerActionTable(convertTable(detailReport.getDangerActionTable()));
		currentCompareReport.setDangerStatusTable(convertTable(detailReport.getDangerStatusTable()));
		setCompareTotalTable(currentCompareReport);

		problemDao.fullfillHSEMonthCompareReportRemoteCauseTable(currentCompareReport, dateStart, dateEnd, remoteCauseIDArray);

		report.setCurrentCompareReport(currentCompareReport);
	}

	private void setHSEPreviousMonthCompareReport(HSEReport<HSEReportUnit> report, Long depart1ID, Long equipID, String dateStart) {
		Calendar calStart = Util.convertStrToDate(dateStart);
		int[] timeArray = Util.getDate(calStart);
		int year = timeArray[0], month = timeArray[1];
		if (month == 1) {
			year--;
		}
		month = (month - 1) % 12;

		// Find out previous data in DB
		HSEProblemDao problemDao = DaoCreator.createHSEProblemDao();
		HSEMonthCompareReport<HSEReportUnit> previousCompareReport = new HSEMonthCompareReport<HSEReportUnit>();
		previousCompareReport = problemDao.getHSECompareReport(year, month, depart1ID, equipID, previousCompareReport);

		if (previousCompareReport == null) {
			// Create previous report
			int monthEnd = Util.getMonthEnd(year, month);
			Calendar perviousStart = Util.getCalendar(new int[] { year, month, 1, 0, 0, 0 });
			Calendar previousEnd = Util.getCalendar(new int[] { year, month, monthEnd, 23, 59, 59 });
			String perviousDateStart = Util.formatDate(perviousStart);
			String previousDateEnd = Util.formatDate(previousEnd);

			HSEReport<HSEReportUnit> previousReport = new HSEReport<HSEReportUnit>();
			setHSEDepartMonthDetailReport(previousReport, depart1ID, equipID, perviousDateStart, previousDateEnd);
			setHSECurrentMonthCompareReport(previousReport, depart1ID, equipID, perviousDateStart, previousDateEnd);

			previousCompareReport = previousReport.getCurrentCompareReport();
			// Store it in DB
			problemDao.addHSECompareReport(previousCompareReport);
		}

		report.setPreviousCompareReport(previousCompareReport);
	}

	private void setHSEPreviousMonthCompareReport(HSEReport<HSEReportUnit> report, String dateStart) {
		Calendar calStart = Util.convertStrToDate(dateStart);
		int[] timeArray = Util.getDate(calStart);
		int year = timeArray[0], month = timeArray[1];
		if (month == 1) {
			year--;
		}
		month = (month - 1) % 12;

		// Find out previous data in DB
		HSEProblemDao problemDao = DaoCreator.createHSEProblemDao();
		HSEMonthCompareReport<HSEReportUnit> previousCompareReport = new HSEMonthCompareReport<HSEReportUnit>();
		previousCompareReport = problemDao.getHSECompareReport(year, month, null, null, previousCompareReport);

		if (previousCompareReport == null) {
			// Create previous report
			int monthEnd = Util.getMonthEnd(year, month);
			Calendar perviousStart = Util.getCalendar(new int[] { year, month, 1, 0, 0, 0 });
			Calendar previousEnd = Util.getCalendar(new int[] { year, month, monthEnd, 23, 59, 59 });
			String perviousDateStart = Util.formatDate(perviousStart);
			String previousDateEnd = Util.formatDate(previousEnd);

			HSEReport<HSEReportUnit> previousReport = new HSEReport<HSEReportUnit>();
			setHSECorpMonthDetailReport(previousReport, perviousDateStart, previousDateEnd);
			setHSECurrentMonthCompareReport(previousReport, perviousDateStart, previousDateEnd);

			previousCompareReport = previousReport.getCurrentCompareReport();
			// Store it in DB
			problemDao.addHSECompareReport(previousCompareReport);
		}

		report.setPreviousCompareReport(previousCompareReport);
	}

}
